package org.example.util;

/**
 * @author: zk
 * @date: 2023/6/17 20:22
 */
public class NumberUtil {

    private static final char[] CHAR_ARRAY = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
    private static final String LONG_MIN_TO_BASE62 = "-aZl8N0y58M8";

    /**
     * 10进制转62进制
     * @param number Long 类型10进制数
     * @return String 类型62进制数
     */
    public static String base10ToBase62(Long number) {
        if (number == Long.MIN_VALUE) {
            return LONG_MIN_TO_BASE62;
        }

        final int scale = 62;
        StringBuilder builder = new StringBuilder();
        boolean negative = number < 0;
        if (negative) {
            number = -number;
        }

        int remainder;
        while (number != 0) {
            remainder = (int) (number % scale);
            builder.append(CHAR_ARRAY[remainder]);
            number /= scale;
        }
        if (negative) {
            builder.append('-');
        }
        return builder.reverse().toString();
    }

    /**
     * 62进制转10进制
     * @param numberStr String 类型62进制数
     * @return Long 类型10进制数
     */
    public static Long base62ToBase10(String numberStr) {
        if (LONG_MIN_TO_BASE62.equals(numberStr)) {
            return Long.MIN_VALUE;
        }

        final int scale = 62;
        long result = 0;
        int len = numberStr.length(), i = 0;
        if (len > 0) {
            boolean negative = numberStr.charAt(0) == '-';
            if (negative) {
                i++;
            }

            int index;
            for (; i < len; i++) {
                char c = numberStr.charAt(i);
                if (Character.isDigit(c)) {
                    index = c - '0';
                } else if (Character.isLowerCase(c)) {
                    index = c - 'a' + 10;
                } else if (Character.isUpperCase(c)) {
                    index = c - 'A' + 36;
                } else {
                    throw new  IllegalArgumentException("输入有误！");
                }
                result = result * scale + index;
            }
            if (negative) {
                result = -result;
            }
        }
        return result;
    }
}
